﻿

namespace FimCmTools.Providers
{
    using System;
    using System.Globalization;
    using System.IO;
    using System.Security.Cryptography;
    using System.Text;
    using Microsoft.Clm;
    using FimCmTools.Common;
    public class CustomSecretProvider : ISecretProvider
    {
        private Encoding _encoding;
        /// <summary>
        /// Gets the encoding.
        /// </summary>
        public Encoding Encoding
        {
            get
            {
                if(null==_encoding)
                    _encoding = new ASCIIEncoding();
                return _encoding;
            }
            private set
            {
                _encoding = value;
            }
        }
        public byte[] CalculateHash(string[] secrets)
        {
            if (secrets != null)
            {
                byte[] numArray = null;
                MemoryStream memoryStream = new MemoryStream(128);
                int length = 0;
                for (int i = 0; i < (int)secrets.Length; i++)
                {
                    byte[] bytes = Encoding.GetBytes(SanitizeSecret(secrets[i]));
                    memoryStream.Write(bytes, 0, (int)bytes.Length);
                    length = length + (int)bytes.Length;
                }
                memoryStream.SetLength((long)length);
                memoryStream.Seek((long)0, SeekOrigin.Begin);
                SHA1 sHA1 = SHA1.Create();
                numArray = sHA1.ComputeHash(memoryStream);
                memoryStream.Close();
                return numArray;
            }
            else
            {
                throw new ArgumentNullException("secrets");
            }
        }

        /// <summary>
        /// Gets the expiration period.
        /// </summary>
        public TimeSpan ExpirationPeriod
        {
            get {
                string temp = Utilities.GetConfigString("ExpirationPeriod", "00:20:00");
                TimeSpan ts = new TimeSpan(0, 20, 0);
                if (!TimeSpan.TryParse(temp, out ts))
                {
                    ts = new TimeSpan(0, 20, 0);
                }
                return ts;
            }
        }

        /// <summary>
        /// Generates the secrets.
        /// </summary>
        /// <param name="request">The request.</param>
        public void GenerateSecrets(Microsoft.Clm.Common.Requests.Request request)
        {
            if (string.IsNullOrEmpty(_secret))
                _secret = "123456";
        }

        public DateTime GetExpirationDate(Microsoft.Clm.Common.Requests.Request request)
        {
            return DateTime.UtcNow.Add(ExpirationPeriod);
        }

        /// <summary>
        /// Gets the secrets.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns></returns>
        public string[] GetSecrets(Microsoft.Clm.Common.Requests.Request request)
        {
            return new string[] { _secret??"123456" };
        }

        private string _secret;
        public void Initialize(string data)
        {
            if(!string.IsNullOrEmpty(data))
                _secret = data;
        }

        public int NumberOfSecrets
        {
            get { return 1; }
        }

        public bool ValidateSecretIntegrity(string secret)
        {
            return true;
        }

        public bool ValidateUserSecrets(string[] secrets, Microsoft.Clm.Common.Requests.Request request, bool throwException)
        {
            return true;
        }

        #region Helpers
        protected virtual string SanitizeSecret(string secret)
        {
            string upper = null;
            if (secret != null)
            {
                upper = secret.Trim().ToUpper(CultureInfo.InvariantCulture);
                upper = upper.Replace(" ", "");
                upper = upper.Replace("-", "");
                upper = upper.Replace("O", "0");
                upper = upper.Replace("I", "1");
                upper = upper.Replace("L", "1");
                return upper;
            }
            else
            {
                return null;
            }
        }
        #endregion

    }
}
